package com.td.module.agro.service.review;

import cn.hutool.core.util.IdUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.td.framework.common.pojo.PageResult;
import com.td.framework.common.util.collection.CollectionUtils;
import com.td.module.agro.controller.admin.review.vo.ReviewCreateReqVO;
import com.td.module.agro.controller.admin.review.vo.ReviewExportReqVO;
import com.td.module.agro.controller.admin.review.vo.ReviewPageReqVO;
import com.td.module.agro.controller.admin.review.vo.ReviewUpdateReqVO;
import com.td.module.agro.convert.input.InputConvert;
import com.td.module.agro.convert.review.ReviewConvert;
import com.td.module.agro.dal.dataobject.input.InputDO;
import com.td.module.agro.dal.dataobject.inputreview.InputReviewDO;
import com.td.module.agro.dal.dataobject.review.ReviewDO;
import com.td.module.agro.dal.mysql.input.InputMapper;
import com.td.module.agro.dal.mysql.inputreview.InputReviewMapper;
import com.td.module.agro.dal.mysql.review.ReviewMapper;
import com.td.module.infra.api.file.FileApi;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
//import static com.td.module.agro.enums.ErrorCodeConstants.java.*;


/**
 * 溯源信息 Service 实现类
 *
 * @author 吴佰强
 */
@Service
@Validated
public class ReviewServiceImpl implements ReviewService {

    @Resource
    private ReviewMapper reviewMapper;

    @Resource
    private InputMapper inputMapper;

    @Resource
    private InputReviewMapper inputReviewMapper;

    @Resource
    private FileApi fileApi;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createReview(ReviewCreateReqVO createReqVO) {
        // 插入
        ReviewDO review = ReviewConvert.INSTANCE.convert(createReqVO);
        //生成溯源码
        review.setAgroCode(IdUtil.simpleUUID());
        //生成溯源码二维码并上传OSS
        byte[] pngBytes = QrCodeUtil.generatePng(review.getAgroCode(), 300, 300);
        String agroCodeImg = fileApi.createFile(pngBytes);
        review.setAgroCodeImg(agroCodeImg);

        reviewMapper.insert(review);
        //插入投入品
        List<InputDO> inputDOS = InputConvert.INSTANCE.convertBatch(createReqVO.getInputCreateReqVOS());
        inputMapper.insertBatch(inputDOS);
        //插入中间表
        inputDOS.stream().map(InputDO::getId).collect(Collectors.toList()).forEach(inputId -> {
            InputReviewDO inputReviewDO = new InputReviewDO();
            inputReviewDO.setReviewId(review.getId());
            inputReviewDO.setInputId(inputId);
            inputReviewMapper.insert(inputReviewDO);
        });
        // 返回
        return review.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateReview(ReviewUpdateReqVO updateReqVO) {
        // 校验存在
//        this.validateReviewExists(updateReqVO.getId());
        // 更新
        ReviewDO updateObj = ReviewConvert.INSTANCE.convert(updateReqVO);
        reviewMapper.updateById(updateObj);
        //更新投入品
        List<InputDO> inputDOS = InputConvert.INSTANCE.convertBatchUpdate(updateReqVO.getInputUpdateReqVOS());
        inputDOS.forEach(inputDO -> {
            inputMapper.updateById(inputDO);
        });
        //更新中间表
        inputReviewMapper.delete(new QueryWrapper<InputReviewDO>().eq("review_id", updateObj.getId()));
        inputDOS.stream().map(InputDO::getId).collect(Collectors.toList()).forEach(inputId -> {
            InputReviewDO inputReviewDO = new InputReviewDO();
            inputReviewDO.setReviewId(updateObj.getId());
            inputReviewDO.setInputId(inputId);
            inputReviewMapper.insert(inputReviewDO);
        });
        // 返回

    }

    @Override
    public void deleteReview(Long id) {
        // 校验存在
//        this.validateReviewExists(id);
        // 删除
        reviewMapper.deleteById(id);
        List<InputReviewDO> inputReviewDOS = inputReviewMapper.selectList(new QueryWrapper<InputReviewDO>().eq("review_id", id));
        if (!CollectionUtils.isAnyEmpty(inputReviewDOS)) {
            inputReviewDOS.forEach(inputReviewDO -> {
                inputMapper.deleteById(inputReviewDO.getInputId());
            });
        }
        inputReviewMapper.delete(new QueryWrapper<InputReviewDO>().eq("review_id", id));
    }

//    private void validateReviewExists(Long id) {
//        if (reviewMapper.selectById(id) == null) {
//            throw exception(REVIEW_NOT_EXISTS);
//        }
//    }

    @Override
    public ReviewUpdateReqVO getReview(Long id) {
        ReviewUpdateReqVO updateReqVO = new ReviewUpdateReqVO();
        BeanUtils.copyProperties(reviewMapper.selectById(id), updateReqVO);
        updateReqVO.setInputUpdateReqVOS(
                InputConvert.INSTANCE.convertBatchUpdate02(inputMapper.selectBatchIds(inputReviewMapper.
                        selectList(new QueryWrapper<InputReviewDO>().eq("review_id", id)).stream().
                        map(InputReviewDO::getInputId).collect(Collectors.toList()))));
        return updateReqVO;
    }

    @Override
    public List<ReviewDO> getReviewList(Collection<Long> ids) {
        return reviewMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<ReviewDO> getReviewPage(ReviewPageReqVO pageReqVO) {
        return reviewMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ReviewDO> getReviewList(ReviewExportReqVO exportReqVO) {
        return reviewMapper.selectList(exportReqVO);
    }

}
